# -*- coding: utf-8 -*-
import logging
import random
import string
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
from integration.utils.WaitUntil import WaitUntil
from selenium.webdriver.common.keys import Keys
from integration.utils.DirAndTime import *
from integration.utils.mysql_select import MysqlSelect
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.ie.options import Options as IEOptions
from selenium.webdriver.edge.options import Options as EdgeOptions

driver = None
wait_util = None
driver: webdriver.Chrome
wait_util: WaitUntil(driver)

GRID_URL = 'http://101.201.29.97:8083//wd/hub'
# 任意浏览器版本
DEFAULT_BROWSER_VERSION = ''
# 随机node节点
DEFAULT_PLATFORM = 'ANY'


# 实现元素查找功能（替代原 ele_object）
def get_element(driver, by, locator):
    if by == "id":
        return driver.find_element(By.ID, locator)
    elif by == "name":
        return driver.find_element(By.NAME, locator)
    elif by == "class":
        return driver.find_element(By.CLASS_NAME, locator)
    elif by == "xpath":
        return driver.find_element(By.XPATH, locator)
    elif by == "link_text":
        return driver.find_element(By.LINK_TEXT, locator)
    elif by == "partial_link_text":
        return driver.find_element(By.PARTIAL_LINK_TEXT, locator)
    elif by == "tag_name":
        return driver.find_element(By.TAG_NAME, locator)
    elif by == "css_selector":
        return driver.find_element(By.CSS_SELECTOR, locator)
    else:
        raise ValueError(f"Unsupported locator type: {by}")


# # 打开浏览器
# def open_browser(browser, browser_version=DEFAULT_BROWSER_VERSION, platform_name=DEFAULT_PLATFORM):
#     global driver, wait_util
#     try:
#         # options = create_browser_options(browser, browser_version, platform_name)
#         #
#         # # 创建远程WebDriver
#         # driver = webdriver.Remote(
#         #     command_executor=GRID_URL,
#         #     options=options
#         # )
#         if browser.lower() == 'ie':
#             options = IEOptions()
#             options.set_capability('browserName', 'internet explorer')
#             # 设置平台和版本
#             options.set_capability('platformName', platform_name)
#             options.set_capability('browserVersion', browser_version)
#             # 设置其他通用选项
#             options.set_capability('se:javascriptEnabled', True)
#             # 连接到 Selenium Grid
#             driver = webdriver.Remote(
#                 command_executor=GRID_URL,
#                 options=options
#             )
#         elif browser.lower() == 'chrome':
#             options = ChromeOptions()
#             options.set_capability('browserName', 'chrome')
#             # 设置平台和版本
#             options.set_capability('platformName', platform_name)
#             options.set_capability('browserVersion', browser_version)
#             # 设置其他通用选项
#             options.set_capability('se:javascriptEnabled', True)
#             # 连接到 Selenium Grid
#             driver = webdriver.Remote(
#                 command_executor=GRID_URL,
#                 options=options
#             )
#         elif browser.lower() == 'edge':
#             options = EdgeOptions()
#             options.set_capability('browserName', 'MicrosoftEdge')
#             # 设置平台和版本
#             options.set_capability('platformName', platform_name)
#             options.set_capability('browserVersion', browser_version)
#             # 设置其他通用选项
#             options.set_capability('se:javascriptEnabled', True)
#             # 连接到 Selenium Grid
#             driver = webdriver.Remote(
#                 command_executor=GRID_URL,
#                 options=options
#             )
#         elif browser.lower() == 'firefox':
#             options = FirefoxOptions()
#             options.set_capability('browserName', 'firefox')
#             options.set_capability('platformName', platform_name)
#             options.set_capability('browserVersion', browser_version)
#             # 设置其他通用选项
#             options.set_capability('se:javascriptEnabled', True)
#             # 连接到 Selenium Grid
#             driver = webdriver.Remote(
#                 command_executor=GRID_URL,
#                 options=options
#             )
#         else:
#             raise ValueError(f"不支持的浏览器: {browser}")
#
#     except Exception as e:
#         raise e
#     else:
#         wait_util = WaitUntil(driver)  # driver 创建之后， 创建等待类实例对象


# 打开浏览器
def open_browser(browser):
    global driver, wait_util
    try:
        if browser.lower() == 'ie':
            # driver = webdriver.Ie(iePath)
            driver = webdriver.Ie()
        elif browser.lower() == 'chrome':
            # driver = webdriver.Chrome(chromePath)
            driver = webdriver.Chrome()
        elif browser.lower() == 'edge':
            driver = webdriver.Edge()
        else:
            # driver = webdriver.Firefox(fireFox)
            driver = webdriver.Firefox()
    except Exception as e:
        raise e
    else:
        wait_util = WaitUntil(driver)  # driver 创建之后， 创建等待类实例对象


# 浏览器窗口最大化
def maximize_browser():
    try:
        driver.maximize_window()
    except Exception as e:
        raise e


def assertdy(text1, ys, fs, *args):  # 接受任意额外参数，但只用前 3 个
    if fs == "xpath":
        textdy = driver.find_element(By.XPATH, text1).text
        assert textdy == ys, f"断言失败: {textdy} ≠ {ys}"
        print(f"实际获取的文本: {textdy}")
        print(f"预期获取的文本: {ys}")


# 加载网址
def load_url(url):
    """
    :param url: 地址
    :return:
    """
    try:
        driver.get(url)
    except Exception as e:
        raise e


# todo 切换页面
def window_handles():
    driver.switch_to.window(driver.window_handles[-1])


# 强制等待
def sleep(sleep_seconds):
    try:
        import time
        time.sleep(sleep_seconds)
    except Exception as e:
        raise e


# 清空输入的内容
def clear(by, locator):
    try:
        get_element(driver, by, locator).clear()
    except Exception as e:
        raise e


# 输入框中输入内容
def input_value(by, locator, value):
    try:
        element = get_element(driver, by, locator)
        # element.click()
        element.send_keys(value)
    except Exception as e:
        raise e


def execute_script():
    import time
    # 方法一：坐标法
    driver.execute_script('window.scrollTo(0,500)')  # 横坐标不变，纵坐标 滚动到1000像素点
    time.sleep(2)  # 等待一段时间，方便查看滚动的效果


# def input_random_str_value(by, locator, value, length):
#     """
#     输入拼接上的随机字符串的内容
#     :param by: 定位方式
#     :param locator: 定位元素值
#     :param value: 输入内容
#     :param length: 拼接随机字符串长度
#     :return:
#     """
#     try:
#         length = int(length)
#         rand_str = ''.join(random.choices(string.ascii_letters + string.digits, k=length))
#         full_value = value + rand_str
#         element = get_element(driver, by, locator)
#         element.send_keys(full_value)
#     except Exception as e:
#         raise e


def input_random_str_value(by, locator, value):
    """
    输入拼接上的随机字符串的内容
    :param by: 定位方式
    :param locator: 定位元素值
    :param value: 输入内容
    :param length: 拼接随机字符串长度
    :return:
    """
    try:
        length = int(5)
        rand_str = ''.join(random.choices(string.ascii_letters + string.digits, k=length))
        full_value = value + rand_str
        element = get_element(driver, by, locator)
        element.send_keys(full_value)
    except Exception as e:
        raise e


# def input_random_int_value(by, locator, value, start, end):
#     """
#     拼接上的范围内的数字
#     :param by: 定位方式
#     :param locator: 定位元素值
#     :param value: 输入内容
#     :param start: 开始范围
#     :param end: 结束范围
#     :return:
#     """
#     try:
#         start = int(start)  # 转换为整数
#         end = int(end)
#         rand_num = random.randint(start, end)
#         full_value = value + str(rand_num)
#         element = get_element(driver, by, locator)
#         element.send_keys(full_value)
#     except Exception as e:
#         raise e

def input_random_int_value(by, locator):
    """
    拼接上的范围内的数字
    :param by: 定位方式
    :param locator: 定位元素值
    :param value: 输入内容
    :param start: 开始范围
    :param end: 结束范围
    :return:
    """
    try:
        start = int(0)  # 转换为整数
        end = int(100000000)
        rand_num = random.randint(start, end)
        full_value = str(rand_num)
        element = get_element(driver, by, locator)
        element.send_keys(full_value)
    except Exception as e:
        raise e


# 点击操作
def click_btn(by, locator):
    try:
        get_element(driver, by, locator).click()
    except Exception as e:
        raise e


# 断言页面的title
def assert_title(title_str):
    try:
        assert title_str in driver.title, "%s not found in title!" % title_str
    except AssertionError as e:
        raise AssertionError(e)
    except Exception as e:
        raise e


# 断言目标字符串是否包含在页面源码中
def assert_string_in_page_source(assert_string):
    try:
        assert assert_string in driver.page_source, "%s not found in page source!" % assert_string
    except AssertionError as e:
        raise AssertionError(e)
    except Exception as e:
        raise e


# 获取当前页面的title
def get_title():
    try:
        return driver.title
    except Exception as e:
        raise e


# 获取页面源码
def get_page_source():
    try:
        return driver.page_source
    except Exception as e:
        raise e


# 切换到frame里面
def switch_to_frame(by, locator):
    try:
        driver.switch_to.frame(get_element(driver, by, locator))
    except Exception as e:
        raise e


# 跳到默认的frame
def switch_to_default():
    try:
        driver.switch_to.default_content()
    except Exception as e:
        raise e


# 屏幕截图
def save_screen_shot():
    picture_name = DirAndTime.create_picture_path() + '\\' + DirAndTime.get_current_time() + '.png'
    try:
        driver.get_screenshot_as_file(picture_name)
    except Exception as e:
        raise e
    else:
        return picture_name


def wait_presence_of_element_located(by, locator):
    """
    显示等待页面元素出现在DOM中，不一定可见
    :param by:
    :param locator:
    :return:
    """
    wait_util.presence_of_element_located(by, locator)


def wait_frame_to_be_available_and_switch_to_it(by, locator):
    """
    检查frame是否存在，存在就切换到frame中
    :param by:
    :param locator:
    :return:
    """
    wait_util.frame_to_be_available_and_switch_to_it(by, locator)


def wait_visibility_of_element_located(by, locator):
    """
    显示等待页面元素出现在DOM中，并且可见
    :param by:
    :param locator:
    :return:
    """
    wait_util.visibility_of_element_located(by, locator)


# 关闭浏览器
def quit_browser():
    """安全关闭浏览器"""
    try:
        if 'driver' in globals() and driver:
            driver.quit()
            print("浏览器已成功关闭")
    except Exception as e:
        print(f"关闭浏览器时出错: {str(e)}")


def assert_mysql_first_value(table, key_data=None, value_data=None, param=None, assert_value=None):
    """
    断言单条数据, 获取对应的字段的值
    :param table: 表名
    :param key_data: 判断的字段名用[]传入，[字段1,字段2,字段3]
    :param value_data: 判断的字段值用[]传入，[值1,值2,值3]
    :param param: 你所要获取到字段的条件
    :param assert_value: 要断言的值
    :return:
    """
    if key_data:
        # key_data = [f'{key_data}']
        key_data = key_data

    if value_data:
        # value_data = [f'{value_data}']
        value_data = value_data
    result = MysqlSelect().mysql_select_first(table, key_data, value_data, param)
    assert assert_value == result, f'预期结果是：{assert_value},实际结果是：{result},断言不通过'
    logging.info(f'预期结果是：{assert_value},实际结果是：{result},断言通过')


def assert_mysql_length(table, key_data=None, value_data=None, assert_value=None):
    """
    断言获取到符合条件数据的数量
    :param table: 表名
    :param key_data: 判断的字段名用[]传入，[字段1,字段2,字段3]
    :param value_data: 判断的字段值用[]传入，[值1,值2,值3]
    :param assert_value: 预期长度
    :return:
    """
    if key_data:
        # key_data = [f'{key_data}']
        key_data = key_data

    if value_data:
        # value_data = [f'{value_data}']
        value_data = value_data

    result = MysqlSelect().mysql_length(table, key_data, value_data)
    assert assert_value == result, f'预期存在数据数量：{assert_value},实际存在数据数量：{result},断言不通过'
    logging.info(f'预期存在数据数量：{assert_value},实际存在数据数量：{result},断言通过')


if __name__ == '__main__':
    from time import sleep

    # open_browser('firefox')
    # load_url('http://www.baidu.com')
    # input_value('id', 'kw', 'python')
    # clear('id', 'kw')
    # input_value('id', 'kw', 'python')
    # click_btn('id', 'su')
    # sleep(3)
    # title = get_title()
    # print(title)
    # assert_title('python')
    # assert_string_in_page_source('python')
    # # ctrl_v('python')
    # sleep(3)
    # quite_browser()

    # assert_mysql_first_value('y_user', "username", "admin", 'pwd', 'ebcbf97ec1d80c0388d39bf508039baa')
    # assert_mysql_first_value('area', ["name", "sort"], ['上地', '2'], 'atype', 2)
    # assert_mysql_length('y_user', "username", "admin", 1)
    # assert_mysql_length('area', ["name", "sort"], ["上地", '2'], 1)
